/*
 *  Author: DL
 *  Date: 2021-01-07 14:22:41
 *  Email: dunaliang@fengmap.com
 *  LastEditTime: 2021-08-12 18:05:36
 *  LastEditors: DL
 *  Description:
 *  Copyright: Copyright 2014 - 2021, FengMap, Ltd. All rights reserved.
 */

import mibee from './mibee';
import updateOrientation from './direction';

var angle = 0,
  stepAndAngle = [],
  locationX = 0,
  locationY = 0,
  level = 0;
var gravityOld = 0,
  lastStatus = false,
  isDirectionUp = false,
  continueUpCount = 0,
  continueUpFormerCount = 0,
  timeOfThisPeak = 0,
  timeOfLastPeak = 0;
var timeOfNow = 0,
  TimeInterval = 250,
  peakOfWave = 0,
  valleyOfWave = 0,
  ThreadValue = 2.0;
var InitialValue = 1.3,
  tempCount = 0,
  ValueNum = 4,
  tempValue = [4];
var Cha_X = 0,
  Cha_Y = 0,
  Cha_Count = 0;
var flag = false;
var Show_X = 0,
  Show_Y = 0;

function Subject() {
  this.timer = 0;
  this.observers = [];
}

Subject.prototype.add = function(observer) {
  this.observers.push(observer);
};

Subject.prototype.remove = function(observer) {
  const index = this.observers.indexOf(observer);
  this.observers.split(index, 1);
};

Subject.prototype.notice = function(coordinate) {
  this.observers.forEach(item => {
    const fn = item ? item : null;

    if (fn) {
      const { type } = coordinate;

      if (type === 'Bluetooth') {
        this.timer = 0;

        if (coordinate && coordinate.x) {
          stepAndAngle = [];

          locationX = Show_X;
          locationY = Show_Y;
          level = coordinate.level;

          if (Show_X !== 0) {
            Cha_X = coordinate.x - Show_X;
            Cha_Y = coordinate.y - Show_Y;
            Cha_Count = 0;
          } else {
            locationX = coordinate.x;
            locationY = coordinate.y;
            console.log('show location');
            fn({ x: locationX, y: locationY, level: 1, type: 'Bluetooth', name: '我的位置' });
            // that.addOrMoveLocationMarker(that.data.Location_x, that.data.Location_y, 1, that.data.angle);
          }

          // if (flag === false) {
          //   fn(coordinate);
          //   flag = true;
          // } else {
          //   if (Show_X !== 0) {
          //     Cha_X = coordinate.x - Show_X;
          //     Cha_Y = coordinate.y - Show_Y;
          //     Cha_Count = 0;
          //   } else {
          //     locationX = coordinate.x;
          //     locationY = coordinate.y;
          //   }
          // }
        }
      } else if (type === 'GPS') {
        if (this.timer < 5) {
          this.timer++;
          console.log(`当前获取GPS位置,命中${this.timer}次`);
        } else {
          fn(coordinate);
        }
      } else {
        fn(coordinate);
      }
    }
  });
};

export function location(locationCallback) {
  var subject = new Subject();

  subject.add(locationCallback);

  // 测试
  // simulationLocation(subject);

  // joysuch(subject);

  // 美迪
  // bluetoothLocation(subject);

  // GPS
  // gpsLocation(subject);

  mibee(subject);

  runStep(locationCallback);
}

// funciton accelerationIncludingGravityCallback(){ }

function accelerationIncludingGravityCallback(event) {
  var x = event.accelerationIncludingGravity.x;
  var y = event.accelerationIncludingGravity.y;
  var z = event.accelerationIncludingGravity.z;

  let length = Math.sqrt(x * x + y * y + z * z);
  detectorNewStep(length);
  if (length >= 12.52188) {
    var onedata = {
      step: 1,
      angle: angle,
    };
    stepAndAngle.push(onedata);
  }
}

function detectorNewStep(values) {
  if (gravityOld === 0) {
    gravityOld = values;
  } else {
    if (detectorPeak(values, gravityOld)) {
      //timeOfLastPeak = timeOfThisPeak;

      timeOfLastPeak = timeOfThisPeak;
      timeOfNow = new Date().getTime() * 1000;

      if (timeOfNow - timeOfLastPeak >= TimeInterval && peakOfWave - valleyOfWave >= ThreadValue) {
        timeOfThisPeak = timeOfNow;
        /*
         * 更新界面的处理，不涉及到算法
         * */
        console.log('计算一步');
      }

      if (timeOfNow - timeOfLastPeak >= TimeInterval && peakOfWave - valleyOfWave >= InitialValue) {
        timeOfThisPeak = timeOfNow;
        ThreadValue = peakValleyThread(peakOfWave - valleyOfWave);
      }
    }
  }

  gravityOld = values;
}

function peakValleyThread(value) {
  //console.log("peakValleyThread");
  let tempThread = ThreadValue;
  if (tempCount < ValueNum) {
    tempCount = tempCount += 1;
    tempValue[tempCount] = value;
    //this.data.tempCount++;
  } else {
    tempThread = averageValue(tempValue, ValueNum);
    for (var i = 1; i < ValueNum; i++) {
      tempValue[i - 1] = tempValue[i];
    }
    tempValue[ValueNum - 1] = value;
  }
  return tempThread;
}

function averageValue(value, n) {
  let ave = 0;
  for (var i = 0; i < n; i++) {
    ave += value[i];
  }
  ave = ave / ValueNum;
  if (ave >= 8) {
    ave = Number(4.3);
  } else if (ave >= 7 && ave < 8) {
    ave = Number(3.3);
  } else if (ave >= 4 && ave < 7) {
    ave = Number(2.3);
  } else if (ave >= 3 && ave < 4) {
    ave = Number(2.0);
  } else {
    ave = Number(1.3);
  }
  return ave;
}

function detectorPeak(newValue, oldValue) {
  lastStatus = isDirectionUp;

  if (newValue >= oldValue) {
    isDirectionUp = true;
    continueUpCount = continueUpCount += 1;
  } else {
    continueUpFormerCount = continueUpCount;
    continueUpCount = 0;
    isDirectionUp = false;
  }
  if (!isDirectionUp && lastStatus && (continueUpFormerCount >= 2 || oldValue >= 20)) {
    peakOfWave = oldValue;
    return true;
  } else if (!lastStatus && isDirectionUp) {
    valleyOfWave = oldValue;
    return false;
  } else {
    return false;
  }
}

function angleCallback(event) {
  if (event.webkitCompassHeading) {
    angle = event.webkitCompassHeading;
  } else if (event.alpha) {
    angle = Math.abs(event.alpha - 360);
  }
}

function runStep(locationCallback) {
  if (locationX !== 0 && stepAndAngle.length > 0) {
    var chavalue_x = 0;
    var chavalue_y = 0;
    for (var i = 0; i < stepAndAngle.length; i++) {
      var oneAngle = stepAndAngle[i].angle;
      //判断8个方向上的角度
      if (oneAngle < 20 || oneAngle > 340) {
        //角度为0的情况
        chavalue_y += 0.4;
      }
      if (oneAngle < 65 && oneAngle > 25) {
        //角度为45的情况
        chavalue_x += 0.22;
        chavalue_y += 0.22;
      }
      if (oneAngle < 110 && oneAngle > 70) {
        //角度为90的情况
        chavalue_x += 0.44;
      }
      if (oneAngle < 155 && oneAngle > 115) {
        //角度为135的情况
        chavalue_x += 0.22;
        chavalue_y -= 0.22;
      }
      if (oneAngle < 200 && oneAngle > 160) {
        //角度为180的情况
        chavalue_y -= 0.44;
      }
      if (oneAngle < 245 && oneAngle > 205) {
        //角度为225的情况
        chavalue_x -= 0.22;
        chavalue_y -= 0.22;
      }
      if (oneAngle < 290 && oneAngle > 250) {
        //角度为270的情况
        chavalue_x -= 0.44;
      }
      if (oneAngle < 335 && oneAngle > 295) {
        chavalue_x -= 0.22;
        chavalue_y += 0.22; //角度为315的情况
      }
    }

    console.log('Cha_Count', Cha_Count);

    if (Cha_Count < 20 && Show_X != 0 && Show_Y != 0) {
      let x1 = Cha_X / 20;
      let y1 = Cha_Y / 20;
      locationX = x1 + locationX;
      locationY = y1 + locationY;

      console.log(Cha_X);
      console.log(Cha_X / 20);

      Cha_Count += 1;
    }

    Show_X = locationX + chavalue_x;
    Show_Y = locationY + chavalue_y;

    console.log('惯导定位给点' + Show_X + ',' + Show_Y);

    // console.log(`x1:${x1},y1:${y1}`);
    locationCallback({ x: Show_X, y: Show_Y, level: 1, type: 'Bluetooth', name: '我的位置' });
  } else {
    //静止状态处理
    if (Cha_Count < 20 && Show_X != 0 && Show_Y != 0) {
      let x1 = Cha_X / 20;
      let y1 = Cha_Y / 20;
      locationX = locationX + x1;
      locationY = locationY + y1;

      Cha_Count += 1;
    }

    Show_X = locationX;
    Show_Y = locationY;

    locationCallback({ x: Show_X, y: Show_Y, level: 1, type: 'Bluetooth', name: '我的位置' });
  }

  setTimeout(function() {
    runStep(locationCallback);
  }, 200);
}

export function orientation(orientationCallback) {
  updateOrientation(orientationCallback, accelerationIncludingGravityCallback, angleCallback);
}
